package com.meilai.project.service.system.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.meilai.project.entity.system.Dictionary;
import com.meilai.project.exception.CommonException;
import com.meilai.project.mapper.system.DictionaryMapper;
import com.meilai.project.service.system.DictionaryService;
import com.meilai.project.util.PinYinUtil;
import com.meilai.project.util.TreeUtil;
import com.meilai.project.vo.SelectOptionVO;
import com.meilai.project.vo.system.DictionaryVO;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author 张驰
 * @date 2020/8/15 10:09
 */
@Service
public class DictionaryServiceImpl extends ServiceImpl<DictionaryMapper, Dictionary> implements DictionaryService {

    /**
     * 查询字典名称map
     * @param ids 字典id
     * @param hasStatus0 含有禁用
     * @param hasDel 含有删除
     * @return
     */
    @Override
    public Map<Long, String> getNamesMapByIds(List<Long> ids, boolean hasStatus0, boolean hasDel) {
        Map<Long, String> result = new HashMap<>();
        if(CollectionUtils.isEmpty(ids)) return result;

        LambdaQueryWrapper<Dictionary> wq = Wrappers.<Dictionary>lambdaQuery().in(Dictionary::getId, ids);
        if(!hasStatus0) wq.eq(Dictionary::getStatus, 1);
        if(!hasDel) wq.isNull(Dictionary::getDeleted_at);
        List<Dictionary> dicts = list(wq);
        if(CollectionUtils.isEmpty(dicts)) return result;

        return dicts.stream().collect(Collectors.toMap(Dictionary::getId, Dictionary::getName));
    }

    @Override
    public List<Dictionary> list1stAnd2nd(String name, Integer status) {
        // 查询的时候需要处理
        if (StringUtils.isNotEmpty(name) || null != status) {
            List<Integer> ids = baseMapper.listIds(name, status);
            // 处理查询不到ids的情况
            if (ids.size() == 0) {
                ids.add(-99);
            }

            QueryWrapper<Dictionary> queryWrapper = new QueryWrapper<>();
            queryWrapper.in("id", ids);
            queryWrapper.orderByAsc("sort");
            return baseMapper.selectList(queryWrapper);
        } else {
            return baseMapper.list1stAnd2nd(name, status);
        }
    }

    @Override
    public IPage<Dictionary> list3rdAll(Long pid, String name, Integer status, int pageNum, int pageSize) {
        Page<Dictionary> pageObj = new Page<>(pageNum, pageSize);
        List<Dictionary> list = baseMapper.list3rdAll(pageObj, pid, name, status);
        return pageObj.setRecords(list);
    }

    @Override
    public IPage<Dictionary> list4thAll(Long pid, String name, Integer status, int pageNum, int pageSize) {
        Page<Dictionary> pageObj = new Page<>(pageNum, pageSize);
        List<Dictionary> list = baseMapper.list4thAll(pageObj, pid, name, status);
        return pageObj.setRecords(list);
    }

    @Override
    public List<SelectOptionVO> pointTypeSelectOptions() {
        return baseMapper.pointTypeSelectOptions();
    }

    private String getUniqueCode(String code, Long... notId) {
        boolean isEdit = notId != null && notId.length == 1;
        QueryWrapper<Dictionary> qw = new QueryWrapper<Dictionary>();
        qw.eq("code", code).isNull("deleted_at");
        if (isEdit) qw.ne("id", notId[0]);
        List<Dictionary> cs = baseMapper.selectList(qw);
        if (CollectionUtils.isNotEmpty(cs)) {
            return getUniqueCode(code + "1", notId);
        } else {
            return code;
        }
    }

    @Override
    @Transactional
    public int add(Dictionary createParams) {
        if (StringUtils.isEmpty(createParams.getName())) throw new CommonException("名称必填");
        String finalCode = "";
        String curCode = PinYinUtil.getStringPinYin(createParams.getName());
        if (createParams.getPid() == null) throw new CommonException("提交错误，请刷新页面");
        if (createParams.getPid() != 0 && createParams.getLevel() != 1) {
            Dictionary pd = baseMapper.selectById(createParams.getPid());
            finalCode = pd.getCode() + "-" + curCode;
        } else {
            finalCode = curCode;
        }
        createParams.setCode(getUniqueCode(finalCode));
        if (validateCode(null, createParams.getCode())) {
            throw new CommonException("编码已存在，请重新填写");
        }
        try {
            Dictionary obj = new Dictionary();
            BeanUtils.copyProperties(createParams, obj);
            Long pid = createParams.getPid();
            Integer level = createParams.getLevel();
            obj.setRid(pid);
            if (pid == 0 && level == 1) {
                baseMapper.insert(obj);
                obj.setRid(obj.getId());
                return baseMapper.updateById(obj);
            } else {
                if (level == 3 || level == 4) {
                    Dictionary _obj = baseMapper.selectById(createParams.getPid());
                    obj.setRid(_obj.getRid());
                }
                return baseMapper.insert(obj);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    @Override
    @Transactional
    public int edit(Dictionary createParams) {
        if (createParams.getId() == null) return 0;
        Dictionary obj = baseMapper.selectById(createParams.getId());
        if (obj == null) return 0;

        if (StringUtils.isEmpty(createParams.getName())) throw new CommonException("名称必填");
        String finalCode = "";
        String curCode = PinYinUtil.getStringPinYin(createParams.getName());
        if (createParams.getPid() == null) throw new CommonException("提交错误，请刷新页面");
        if (createParams.getPid() != 0 && createParams.getLevel() != 1) {
            Dictionary pd = baseMapper.selectById(createParams.getPid());
            finalCode = pd.getCode() + "-" + curCode;
        } else {
            finalCode = curCode;
        }
        createParams.setCode(getUniqueCode(finalCode, createParams.getId()));

        Dictionary _obj = new Dictionary();
        BeanUtils.copyProperties(createParams, _obj);
        return baseMapper.updateById(_obj);
    }

    @Override
    @Transactional
    public Boolean del(List<Integer> ids) {
        List<Dictionary> list = new ArrayList<>();
        for (Integer id : ids) {
            Dictionary o = new Dictionary();
            o.setId(Long.valueOf(id));
            o.setDeleted_at(LocalDateTime.now());
            list.add(o);
        }
        return updateBatchById(list);
    }

    @Override
    @Transactional
    public Boolean changeStatus(int id, Integer status) {
        Dictionary obj = baseMapper.selectById(id);
        if (obj == null) {
            throw new CommonException("该字典数据不存在");
        }
        obj.setStatus(status);
        return baseMapper.updateById(obj) > 0;
    }

    @Override
    public List<Dictionary> listByCode(String code) {
        long pid = baseMapper.getIdByCode(code);
        return baseMapper.getListByPid(pid);
    }

    @Override
    public List<Dictionary> listByPCodeAll(String code) {
        long pid = baseMapper.getIdByCode(code);
        return baseMapper.getListByPidAll(pid);
    }

    @Override
    public List<Dictionary> listByPCodeAllDoor(String code) {
        long pid = baseMapper.getIdByCode(code);
        return baseMapper.getListByPidAll(pid);
    }

    @Override
    public List<Dictionary> listByTopCodeAll(String code) {
        Long rid = baseMapper.getIdByCode(code);
        if (rid == null) return new ArrayList<>();
        return baseMapper.getListByRidAll(rid);
    }

    @Override
    public List<Dictionary> listByTopCodeAllDoor(String code) {
        Long rid = baseMapper.getIdByCode(code);
        if (rid == null) return new ArrayList<>();
        return baseMapper.getListByRidAll(rid);
    }

    @Override
    public List<Dictionary> listByTopCode(String code) {
        Long rid = baseMapper.getIdByCode(code);
        if (rid == null) return new ArrayList<>();
        return baseMapper.getListByRid(rid);
    }

    @Override
    public List<Dictionary> list4thBy2ndCode(String code) {
        Long pid = baseMapper.getIdByCode(code);
        if (pid == null) return new ArrayList<>();
        return baseMapper.getList4thBy2ndId(pid);
    }

    /**
     * 验证code，存在返回true
     *
     * @param id
     * @param code
     * @return
     */
    @Override
    public Boolean validateCode(Long id, String code) {
        QueryWrapper<Dictionary> queryWrapper = new QueryWrapper<>();
        if (id != null) {
            queryWrapper.ne("id", id);
        }
        queryWrapper.eq("code", code);
        queryWrapper.isNull("deleted_at");
        List<Dictionary> list = baseMapper.selectList(queryWrapper);

        if (list != null && list.size() > 0) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public List<Dictionary> listByCodeNoDel(String code) {
        long pid = baseMapper.getIdByCode(code);
        return baseMapper.getListByPidNoDel(pid);
    }

    @Override
    @Transactional
    public boolean setCompanyPointType(String tenantName, List<Long> ids, List<Dictionary> dicts) {
        removeByIds(ids);
        return baseMapper.saveSetPointTypes(dicts);
    }

    @Override
    public String getDictNames(List<Long> ids) {
        String str = "";
        if (ids == null || ids.size() == 0) {
            return null;
        }
        List<Dictionary> dicts = this.list(Wrappers.<Dictionary>lambdaQuery().isNull(Dictionary::getDeleted_at).in(Dictionary::getId, ids));
        for (int i = 0; i < dicts.size(); i++) {
            if (i == dicts.size() - 1) {
                str += dicts.get(i).getName();
            } else {
                str += dicts.get(i).getName() + "|";
            }
        }
        return str;
    }

    @Override
    public List<DictionaryVO> getTreeDictionaryVODataByCode2level(String code) {
        List<DictionaryVO> resultList = new ArrayList<>();
        List<Dictionary> allList = new ArrayList<>();
        // 加入二级字典数据
        Dictionary one = getOne(Wrappers.<Dictionary>lambdaQuery().eq(Dictionary::getCode, code));
        if (one == null) {
            throw new CommonException("字典数据不存在");
        }
        allList.add(one);
        // 加入一级字典数据
        Dictionary level1Dict = getById(one.getPid());
        allList.add(level1Dict);
        // 加入三级字典数据
        List<Dictionary> level3DictList = listByCode(code);
        allList.addAll(level3DictList);
        // 加入四级字典数据
        List<Dictionary> level4DictList = list4thBy2ndCode(code);
        allList.addAll(level4DictList);
        Map<Long, List<DictionaryVO>> map = allList.stream().map(item -> {
            DictionaryVO vo = new DictionaryVO();
            BeanUtils.copyProperties(item, vo);
            return vo;
        }).collect(Collectors.groupingBy(DictionaryVO::getPid));
        DictionaryVO root = map.get(0L).get(0);
        TreeUtil.TreeForEach(map, root);
        if (root.getChildren() != null && root.getChildren().size() == 1) {
            resultList.addAll(root.getChildren().get(0).getChildren());
        }
        return resultList;
    }
}
